package com.ruoyi.web.domain.warning;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.web.pojo.dto.warning.AggregatedData;
import com.ruoyi.web.pojo.dto.warning.WarningJudgeValue;
import com.ruoyi.web.utils.influxdb.DeviceData;
import com.ruoyi.web.utils.influxdb.DeviceHistoryDataParam;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.apache.commons.collections.CollectionUtils;

/**
 * 五情-传感器-预警配置表
 *
 * @author fwx
 * @since 2024-01-30 15:08:07
 */
@Data
@TableName("tt_warning_config")
@ApiModel(value = "WarningConfig对象", description = "五情-传感器-预警配置表")
public class WarningConfig implements Serializable {

    private static final long serialVersionUID = 1L;

    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;

    @ApiModelProperty("因子名字")
    @TableField("factor_name")
    private String factorName;

    @ApiModelProperty("因子key")
    @TableField("factor_key")
    private String factorKey;

    @ApiModelProperty("因子单位")
    @TableField("factor_unit")
    private String factorUnit;

    @ApiModelProperty("因子类型")
    @TableField("factor_type")
    private String factorType;

    /*
       1  数值高于X
       2  数值低于Y
       3  数值高于X低于Y
       4  数值高于X低于Y且当天超过M
       5  数值高于X低于Y且当天超过M，连续N
       6  数值高于X,持续N
       7  数值低于X,持续N
    */
    @ApiModelProperty("判断条件类型 1 - 6")
    @TableField("judge_type")
    private Integer judgeType;

    @ApiModelProperty("判断条件值")
    @TableField("judge_value")
    private String judgeValue;

    //判断条件值的对象
    @TableField(exist = false)
    private WarningJudgeValue judgeValueObj;

    @ApiModelProperty("预警名称")
    @TableField("warning_name")
    private String warningName;

    @ApiModelProperty("预警等级 1 一级 2 二级 3 三级")
    @TableField("warning_level")
    private String warningLevel;

    @ApiModelProperty("预警内容")
    @TableField("warning_content")
    private String warningContent;

    @ApiModelProperty("决策建议")
    @TableField("warning_recommend")
    private String warningRecommend;

    @ApiModelProperty("用户id")
    @TableField("user_id")
    private Long userId;

    @ApiModelProperty("部门id")
    @TableField("dept_id")
    private Long deptId;

    @ApiModelProperty("用户名")
    @TableField("username")
    private String username;

    @ApiModelProperty("是否启用 0 启用 1 不启用")
    @TableField("is_enable")
    private Integer isEnable;

    @ApiModelProperty("创建时间")
    @TableField("crt_time")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime crtTime;


    public void setJudgeValue(String judgeValue) {
        this.judgeValue = judgeValue;
        this.judgeValueObj = JSONObject.parseObject(judgeValue, WarningJudgeValue.class);
    }

    public void checkJudgeType(){

        WarningJudgeValue judge = this.judgeValueObj;

        // 1  数值高于X
        if(this.judgeType == 1){
            if (judge.getX() == null){
                throw new RuntimeException("判断条件值不符合规则");
            }
        }

        if(this.judgeType == 2){
            if (judge.getY() == null){
                throw new RuntimeException("判断条件值不符合规则");
            }
        }

        if(this.judgeType == 3){
            if (judge.getX() == null || judge.getY() == null){
                throw new RuntimeException("判断条件值不符合规则");
            }
        }

        if(this.judgeType == 6){
            if (judge.getX() == null || judge.getN() == null || judge.getN() <= 0){
                throw new RuntimeException("判断条件值不符合规则");
            }
        }

        if(this.judgeType == 7){
            if (judge.getY() == null || judge.getN() == null || judge.getN() <= 0){
                throw new RuntimeException("判断条件值不符合规则");
            }
        }
    }

    public int durationDay(){
        WarningJudgeValue judge = this.judgeValueObj;

        if(judge.getN() == null || judge.getN() <= 0){
            throw new RuntimeException("持续天数需要大于0");
        }

        return judge.getN();
    }

    /**
     * @desc  判断是否需要进行查询历史数据
     * @author fwx 2024/2/4 14:01
     * @return 不需要 0 , 需要 返回要查询的天数
     **/
    public int judgeTypeStr(){

        if(this.judgeType == 1 || this.judgeType == 2 || this.judgeType == 3){
            return 0;
        }

        if(this.judgeType == 6 || this.judgeType == 7){
            return this.durationDay();
        }

        return 0;
    }

    public String abnormalValue(){

        WarningJudgeValue judge = this.judgeValueObj;

        if(this.judgeType == 1){
            return String.format("%s大于%d%s",factorName,judge.getX(),factorUnit);
        }

        if(this.judgeType == 2){
            return String.format("%s小于%d%s",factorName,judge.getY(),factorUnit );
        }

        if(this.judgeType == 3){
            return String.format("%s小于%d小于%d%s",factorName , judge.getX(), judge.getY(), factorUnit);
        }

        if(this.judgeType == 6){
            return String.format("%s连续%d天大于%d%s",factorName,judge.getN(), judge.getX(),factorUnit);
        }

        if(this.judgeType == 7){
            return String.format("%s连续%d天小于%d%s",factorName,judge.getN(), judge.getY(),factorUnit);
        }

        return null;
    }


    /**
     * @desc  对瞬时值判断是否符合预警
     * @author fwx 2024/2/4 13:48
     **/
    public boolean judgeValueWarning(Double val){

        if(val == null){
            return false;
        }

        WarningJudgeValue judge = this.judgeValueObj;

        //1  数值高于X
        if(this.judgeType == 1){
            return val > judge.getX() ;
        }

        // 2  数值低于Y
        if(this.judgeType == 2){
            return val < judge.getY() ;
        }

        // 3  数值高于X低于Y
        if(this.judgeType == 3){
            return val > judge.getX() && val < judge.getY();
        }

        return false;
    }

    /**
     * @desc  判断历史预警值
     * @author fwx 2024/2/21 15:20
     **/
    public boolean judgeHistroyWarning(List<DeviceData> deviceHistory , String modelKey){

        boolean flag = false;

        //查询n天的数据
//        DeviceHistoryDataParam param = new DeviceHistoryDataParam(device.getDeviceId(), device.getProductId(), day);
//        List<DeviceData> deviceHistory = influxdb2Service.getMonitorDataMapByTime(param);

        Map<String, List<DeviceData>> groupHistory
                = deviceHistory.stream().collect(Collectors.groupingBy(DeviceData::getDataDateStr));

        List<AggregatedData> dataList = groupHistory.values().stream()
                .map(list -> new AggregatedData(list, modelKey))
                .collect(Collectors.toList());

        //判断数据是否连续 是否符合条件
        flag = groupHistory.keySet().size() >= this.judgeTypeStr() ? this.judgeDurationWarning(dataList) : false;

        System.err.println(String.format("要判断的值:%s , 判断条件: %s , 判断的类型: %d ,判断的因子: %s, 是否预警: %b "
                , dataList.toString() + "" , this.getJudgeValue(),this.getJudgeType(),this.getFactorKey(), flag));

        return flag;
    }


    /**
     * @desc  对持续值判断预警
     * @author fwx 2024/2/4 13:48
     **/
    public boolean judgeDurationWarning(List<AggregatedData> list){
        if(CollectionUtils.isEmpty(list)){
            return false;
        }

        WarningJudgeValue judge = this.judgeValueObj;

        //数值高于X,持续N
        if(this.judgeType == 6){
            for (AggregatedData data : list) {
                if(data.getMax() < judge.getX()){
                    return false;
                }
            }
        }

        //数值低于X,持续N
        if(this.judgeType == 7){
            for (AggregatedData data : list) {
                if(data.getMax() > judge.getY()){
                    return false;
                }
            }
        }

        return true;
    }
}
